{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "8b79f3f7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "0208d08712624c068397ceb86f30f47d",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Fetching 5 files:   0%|          | 0/5 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a6929277294243c9b8f4aac4042efea3",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "data/train-00001-of-00005.parquet:   0%|          | 0.00/202M [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "27cea48bd53e4151a98ced3ce9fac846",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "data/train-00003-of-00005.parquet:   0%|          | 0.00/454M [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "258877371b334f1aa5ad22ccbbd8e8c4",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "data/train-00000-of-00005.parquet:   0%|          | 0.00/354M [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "11a534b647224361a9c3943df6683ba2",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "data/train-00004-of-00005.parquet:   0%|          | 0.00/307M [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "69e72fc11ea04943802f6ff7b50ec34d",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "data/train-00002-of-00005.parquet:   0%|          | 0.00/439M [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "'/home/mesolitica/stt/Malaysian-Reasoning-Speech-Instructions'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from huggingface_hub import snapshot_download\n",
    "\n",
    "snapshot_download(\n",
    "    repo_id=\"mesolitica/Malaysian-Reasoning-Speech-Instructions\",\n",
    "    repo_type='dataset',\n",
    "    allow_patterns=\"data/*.parquet\",\n",
    "    local_dir=\"./Malaysian-Reasoning-Speech-Instructions\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "87638bd0",
   "metadata": {},
   "outputs": [],
   "source": [
    "from glob import glob\n",
    "from tqdm import tqdm\n",
    "from multiprocess import Pool\n",
    "import itertools\n",
    "import zipfile\n",
    "import os\n",
    "\n",
    "def chunks(l, n):\n",
    "    for i in range(0, len(l), n):\n",
    "        yield (l[i: i + n], i // n)\n",
    "\n",
    "\n",
    "def multiprocessing(strings, function, cores=6, returned=True):\n",
    "    df_split = chunks(strings, len(strings) // cores)\n",
    "    pool = Pool(cores)\n",
    "    pooled = pool.map(function, df_split)\n",
    "    pool.close()\n",
    "    pool.join()\n",
    "\n",
    "    if returned:\n",
    "        return list(itertools.chain(*pooled))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "00f0c1a5",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/lib/python3/dist-packages/scipy/__init__.py:146: UserWarning: A NumPy version >=1.17.3 and <1.25.0 is required for this version of SciPy (detected version 1.26.4\n",
      "  warnings.warn(f\"A NumPy version >={np_minversion} and <{np_maxversion}\"\n"
     ]
    }
   ],
   "source": [
    "from glob import glob\n",
    "import pandas as pd\n",
    "import os\n",
    "import json\n",
    "from transformers import AutoProcessor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6e637acf",
   "metadata": {},
   "outputs": [],
   "source": [
    "processor = AutoProcessor.from_pretrained(\"Qwen/Qwen2-Audio-7B-Instruct\")\n",
    "tokenizer = processor.tokenizer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6395ad50",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Malaysian-Reasoning-Speech-Instructions/data/train-00000-of-00005.parquet',\n",
       " 'Malaysian-Reasoning-Speech-Instructions/data/train-00001-of-00005.parquet',\n",
       " 'Malaysian-Reasoning-Speech-Instructions/data/train-00002-of-00005.parquet',\n",
       " 'Malaysian-Reasoning-Speech-Instructions/data/train-00003-of-00005.parquet',\n",
       " 'Malaysian-Reasoning-Speech-Instructions/data/train-00004-of-00005.parquet']"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "files = sorted(glob('Malaysian-Reasoning-Speech-Instructions/data/*.parquet'))\n",
    "files"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "906edfd8",
   "metadata": {},
   "outputs": [],
   "source": [
    "!mkdir Malaysian-Reasoning-Speech-Instructions-audio"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "24d2a183",
   "metadata": {},
   "outputs": [],
   "source": [
    "def loop(files):\n",
    "    files, _ = files\n",
    "    data = []\n",
    "    for f in files:\n",
    "        f_only = os.path.split(f)[1].replace('.parquet', '')\n",
    "        df = pd.read_parquet(f)\n",
    "        for i in tqdm(range(len(df))):\n",
    "            new_f = os.path.join('Malaysian-Reasoning-Speech-Instructions-audio', \n",
    "                                 f'{f_only}-{i}.mp3')\n",
    "            with open(new_f, 'wb') as fopen:\n",
    "                fopen.write(df['audio_filename'].iloc[i]['bytes'])\n",
    "            \n",
    "            try:\n",
    "                prompt = json.loads(df['prompt'].iloc[i])\n",
    "                conversation = [\n",
    "                    {\"role\": \"system\", \"content\": 'You are going to enter reasoning mode. First, you try to think step-by-step in Malay. After that, put your final answer.'},\n",
    "                    {\"role\": \"user\", \"content\": [\n",
    "                        {\"type\": \"audio\", \"audio_url\": \"audio.wav\"},\n",
    "                    ]},\n",
    "                    {\"role\": \"assistant\", \"content\": prompt[-1]['content']},\n",
    "                ]\n",
    "                text = processor.apply_chat_template(conversation, tokenize=False)\n",
    "            except Exception as e:\n",
    "                continue\n",
    "            \n",
    "            data.append({\n",
    "                'text': text,\n",
    "                'audio': new_f,\n",
    "            })\n",
    "    return data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "7aa6b421",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████████████████████████████████████████████████████████████████████████████| 5038/5038 [00:01<00:00, 3092.16it/s]\n"
     ]
    }
   ],
   "source": [
    "processed = loop((files[:1], 0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "4983022d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5038"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(processed)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "1e4f60b3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<|im_start|>system\n",
      "You are going to enter reasoning mode. First, you try to think step-by-step in Malay. After that, put your final answer.<|im_end|>\n",
      "<|im_start|>user\n",
      "Audio 1: <|audio_bos|><|AUDIO|><|audio_eos|>\n",
      "<|im_end|>\n",
      "<|im_start|>assistant\n",
      "Saya akan melakukan analisis **panjang dan terperinci** seperti yang anda minta. Pertama sekali, mari kita lihat ayat dalam dialek Pahang ini dan cuba kita memahami komponen-komponennya satu persatu.\n",
      "\n",
      "## **Teks Dialek:**\n",
      "\n",
      "**\"Dia dengkat lepaih jatoh pokok.\"**\n",
      "\n",
      "## **Langkah 1: Memahami Konteks dan Nada Ayat**\n",
      "\n",
      "Sebelum kita pecahkan ayat ini, penting untuk mendapatkan idea tentang **konteks dan nada** di sebalik perkataan-perkataan ini. Ayat ini kelihatan seperti satu pernyataan yang menggambarkan keadaan seseorang selepas kejadian tertentu, iaitu jatuh dari pokok.\n",
      "\n",
      "Kita boleh meneka bahawa **nada** ayat ini **netral atau informatif**, tanpa menunjukkan emosi yang kuat seperti kemarahan atau kegembiraan. Namun, **kesan perkataan seperti \"dengkat\" mungkin menambah sedikit nuansa humor atau ironi**.\n",
      "\n",
      "## **Langkah 2: Pemecahan Ayat Menjadi Komponen-Komponen Utama**\n",
      "\n",
      "Sekarang, kita akan memisahkan ayat ini kepada beberapa bahagian berdasarkan tatabahasa:\n",
      "\n",
      "1. **Dia**\n",
      "2. **Dengkat**\n",
      "3. **Lepaih**\n",
      "4. **Jatoh**\n",
      "5. **Pokok**\n",
      "\n",
      "Pemisahan ini akan memudahkan kita untuk memahami fungsi setiap perkataan dan hubungan mereka dalam ayat.\n",
      "\n",
      "## **Langkah 3: Analisis Semantik dan Sintaksis Setiap Perkataan**\n",
      "\n",
      "### **1. Dia**\n",
      "\n",
      "* **Jenis**: Kata ganti nama diri ketiga.\n",
      "* **Makna**: Merujuk kepada pihak ketiga – lelaki atau perempuan.\n",
      "* **Kesan**: Biasanya tidak menunjukkan sebarang emosi, melainkan konteks memerlukan makna yang lebih luas.\n",
      "\n",
      "### **2. Dengkat**\n",
      "\n",
      "* **Jenis**: Kata kerja.\n",
      "* **Makna**: Dalam bahasa standard, perkataan ini biasanya digunakan untuk menggambarkan cara berjalan yang tidak sempurna, terutamanya jika kaki seseorang yang pendek sebelah.\n",
      "* **Dialek**: Perkataan \"dengkat\" dalam dialek Pahang bermaksud **berjalan dengan cara yang tidak sempurna, biasanya disebabkan oleh kecederaan atau kecacatan fizikal**. Ini mungkin berasal dari perkataan \"dengkut\" atau \"dengkot\" dalam dialek lain.\n",
      "* **Kesan**: Memberi imej visual tentang cara berjalan yang berbeza dari normal, mungkin menunjukkan kesan buruk dari insiden jatuh dari pokok.\n",
      "\n",
      "### **3. Lepaih**\n",
      "\n",
      "* **Jenis**: Kata hubung.\n",
      "* **Makna**: Dalam bahasa standard, perkataan ini setara dengan \"selepas\" atau \"setelah\".\n",
      "* **Dialek**: \"Lepaih\" dalam dialek Pahang digunakan untuk menunjukkan **urutan masa**, iaitu sesuatu berlaku selepas sesuatu lagi.\n",
      "* **Kesan**: Menyusun urutan peristiwa, menunjukkan bahawa cara berjalan \"dengkat\" itu berlaku **selepas** jatuh dari pokok.\n",
      "\n",
      "### **4. Jatoh**\n",
      "\n",
      "* **Jenis**: Kata kerja.\n",
      "* **Makna**: \"Jatuh\" dalam bahasa standard.\n",
      "* **Dialek**: \"Jatoh\" adalah bentuk ejaan dialek bagi \"jatuh\". Dalam dialek Pahang, bunyi 'u' kadang-kadang diubah kepada 'o'.\n",
      "* **Kesan**: Menggambarkan kejadian yang berlaku terhadap subjek \"dia\" – jatuh dari pokok, yang menjadi **punca** kepada cara berjalan yang \"dengkat\".\n",
      "\n",
      "### **5. Pokok**\n",
      "\n",
      "* **Jenis**: Kata nama.\n",
      "* **Makna**: \"Pokok\" dalam bahasa standard.\n",
      "* **Kesan**: Menyediakan konteks fizikal di mana insiden berlaku, iaitu dari atas pokok.\n",
      "\n",
      "## **Langkah 4: Menyusun Semula Maksud Literally Berdasarkan Komponen-Komponen**\n",
      "\n",
      "Dengan memahami setiap komponen, kita boleh menyusun semula makna literal ayat ini:\n",
      "\n",
      "* **\"Dia dengkat lepaih jatoh pokok\"** = **\"Dia berjalan dengkat (tidak sempurna) selepas jatuh dari pokok.\"**\n",
      "\n",
      "## **Langkah 5: Penyesuaian ke Bahasa Melayu Standard**\n",
      "\n",
      "Walau bagaimanapun, untuk membuat ayat ini lebih **sesuai dengan Bahasa Melayu Standard**, kita boleh memilih beberapa variasi:\n",
      "\n",
      "### **Variasi A – Terus Terjemahan**\n",
      "\n",
      "> **\"Dia berjalan dengkat selepas jatuh dari pokok.\"**\n",
      "\n",
      "### **Variasi B – Tambahan Maklumat**\n",
      "\n",
      "> **\"Selepas jatuh dari pokok, dia terpaksa berjalan dengan cara yang tidak sempurna.\"**\n",
      "\n",
      "### **Variasi C – Gaya Lebih Puitis**\n",
      "\n",
      "> **\"Akibat jatuh dari pokok, langkahnya terpaksa berubah menjadi berjalan dengkat.\"**\n",
      "\n",
      "## **Langkah 6: Refleksi Budaya dan Konteks**\n",
      "\n",
      "Dalam masyarakat Pahang, seperti dalam banyak budaya Melayu lain, penggunaan bahasa yang ringkas tetapi sarat makna adalah sangat lazim. Ayat ini memberikan gambaran singkat tetapi berkesan tentang **kesan fizikal dari kejadian negatif** – jatuh dari pokok – dan **bagaimana ia mempengaruhi pergerakan seseorang**.\n",
      "\n",
      "Selain itu, cara bahasa digunakan dalam ayat ini mencerminkan **kelebihan ekspresi lisan dalam budaya tempatan**, di mana kejadian dan akibatnya disampaikan dengan jelas dan ringkas, tanpa perlu terlalu banyak penjelasan tambahan.\n",
      "\n",
      "## **Kesimpulan**\n",
      "\n",
      "Penterjemahan ayat **\"Dia dengkat lepaih jatoh pokok.\"** kepada Bahasa Melayu Standard boleh dilakukan dengan beberapa variasi, bergantung pada tahap keformalan dan gaya yang dikehendaki. Walau bagaimanapun, penterjemahan yang paling langsung dan tepat ialah:\n",
      "\n",
      "> **\"Dia berjalan dengkat selepas jatuh dari pokok.\"**\n",
      "\n",
      "Ayat ini mengekalkan makna asal sambil menyesuaikan dengan struktur dan kosa kata Bahasa Melayu Standard, tetapi masih mengekalkan nuansa yang disampaikan oleh dialek Pahang.\n",
      "\n",
      "**Jawapan Akhir**\n",
      "\n",
      "$boxed{Dia berjalan dengkat selepas jatuh dari pokok.}$.<|im_end|>\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(processed[-1]['text'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "bc1a7d7c",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████████████████████████████████████████████████████████████████████████████| 5038/5038 [00:01<00:00, 3455.49it/s]\n",
      "100%|█████████████████████████████████████████████████████████████████████████████████| 5038/5038 [00:01<00:00, 3201.08it/s]\n",
      "100%|█████████████████████████████████████████████████████████████████████████████████| 5038/5038 [00:01<00:00, 2960.37it/s]\n",
      "100%|█████████████████████████████████████████████████████████████████████████████████| 5038/5038 [00:01<00:00, 2997.03it/s]\n",
      "100%|█████████████████████████████████████████████████████████████████████████████████| 5038/5038 [00:01<00:00, 2980.57it/s]\n"
     ]
    }
   ],
   "source": [
    "processed = multiprocessing(files, loop, cores = min(len(files), 30))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "fb30a85d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "25190"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(processed)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "0bc96f29",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('prepare-Malaysian-Reasoning-Speech-Instructions.json', 'w') as fopen:\n",
    "    json.dump(processed, fopen)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
